4.3 切片
切片在Go
语言中的应用是比较广泛的,因为它的灵活性,在实际业务开发中,其实比数组使用的还要更多。
本节代码存放目录为 lesson8
什么是切片
在上一节中我们讲到,数组的长度是固定的,不可以变化的,那么在实际的开发中,这样的特性其实对我们是会有一些限制的。
所以产生了切片这样的东西,也就是说切片的长度是可以变化的,这就是切片与数组的最大区别。
由于长度可变的特性,我们可以将切片称之为:动态数组。
声明切片
在上一节中我们讲到了数组的声明,其实切片的声明与数组差不多,由于切片是可以动态变化的,所以我们只需要将之前讲到的长度定义去掉即可。如下所示:
var sliceName []dataType
如下代码所示,根据上面的公式,我们可以定义多种数据类型的切片:
var a []int;
var b []int64;
var c []string;
也可以直接使用make
来创建切片,如下所示:
var d []int = make([]int, 3)
var e []int = make([]int, 3, 4)
在上面的代码中,我们使用make
来创建了切片,在代码中,出现了3
、4
这样的写法。
其实切片的底层可以理解为就是一个数组,所以第一种写法中的3
就是代表着数组的长度为3
,而在第二种写法中,3
同样代表数组的长度,但是4
却代表的是切片的容量。
在这里我们对容量不做过多的阐述,感兴趣的可以去看一下,对于初学者来说这个概念暂时可以不用深入。
与数组的相同点
由于切片的底层是数组,所以数组具备的操作方法,切片同样是具有的,列举如下:
- 可以通过下标获取元素的值
- 可以通过下标修改元素的值
- 可以通过
len
获取切片的长度 - 可以使用
for i...
的方式遍历切片 - 可以使用
for range
的方式遍历切片
切片的新特性
数组具备的特性,切片基本是具备的,那么我们接下来主要说一下切片对比数组的新特性。
append
首先第一个就是append
,从字面意思我们就可以看出,这个关键字的功能是追加,也就是向切片中增加元素。如下所示:
var a []int
a = append(a, 1)
fmt.Println(a[0])
输出结果为:
1
在上面的代码中,我们首先声明了一个名称为a
的切片,之后我们通过append
关键词向a
切片中添加了一个元素1
。
在实际的开发中,我们还可以这样写:
a = append(a, 2, 3)
a = append(a, []int{4, 5}...)
在上面的代码中,我们同时向切片a
中添加了多个元素。
第一种写法是每次都append
一个元素。
第二种写法是一次append
了一个数组,但是需要注意的是,我们使用了...
,那么...
它的作用其实就是把这个数组就打散,相当于最终还是逐个的将4
、5
添加到了切片a
中。
copy
切片可以进行快速的复制,也就是将一个切片复制到一个新的切片中,如下所示:
var b = make([]int, len(a))
copy(b, a)
fmt.Println(b[0])
在上面的代码中,我们首先创建了一个长度与a
一致的新切片b
,之后使用copy
将a
的值赋值到了b
切片中。
切片截取
在切片中,我们可以很方便的截取指定下标范围内的元素。如下所示:
fmt.Println(b[1:3])
输出结果如下:
[2 3]
在上面的代码中,我们通过1:3
截取了下标为1、2
的两个元素,代表的是包含1
,不包含3
,也就是右区间是开区间。
那么基于这一个功能,其实我们就可以实现元素的删除,比如需要删除下标为2
的元素。
那么我们截取出2
以前的元素、2
以后的元素,将其添加到新的切片中,就实现了删除,其实原理也与数组差不多。
小结
在本节我们学习了切片的相关概念,切片与数组相似但又有一些新的特性,可以总结为以下几点:
切片的最底层结构是数组
数组包含的功能切片都包含
切片是一个动态数组,长度可变化
切片可以通过
append
快速添加元素切片可以通过
copy
复制切片可以截取指定的元素